package com.siss.tenancy.user.utils;

import com.siss.tenancy.finals.TenantContextHolder;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.util.Properties;


/**
 * 类名: TenantInterceptor.java
 * 描述: SQL拦截处理多租户
 * 创建人: yingw
 * 创建时间: 2018年7月5日上午9:24:01
 */
@Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class, Integer.class})})
public class DbSchemaInterceptor implements Interceptor {
	public static Logger log = LoggerFactory.getLogger(DbSchemaInterceptor.class);
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        String dbSchema = TenantContextHolder.getSchema();
        if(dbSchema == null || dbSchema == "") {
            //tenant 为空，不需要改写sql语句
            return invocation.proceed();
        }

        if (invocation.getTarget() instanceof RoutingStatementHandler) {
            RoutingStatementHandler statementHandler = (RoutingStatementHandler) invocation
                    .getTarget();
            StatementHandler delegate = (StatementHandler) ReflectHelper
                    .getFieldValue(statementHandler, "delegate");
            BoundSql boundSql = delegate.getBoundSql();
            Object obj = boundSql.getParameterObject();

            // 通过反射获取delegate父类BaseStatementHandler的mappedStatement属性
            MappedStatement mappedStatement = (MappedStatement) ReflectHelper
                    .getFieldValue(delegate, "mappedStatement");
            // 拦截到的prepare方法参数是一个Connection对象
            Connection connection = (Connection) invocation.getArgs()[0];
            // 获取当前要执行的Sql语句，也就是我们直接在Mapper映射语句中写的Sql语句
            String sql = boundSql.getSql();
            // 给当前的page参数对象设置总记录数
            log.debug("处理之前" + sql);
            //对 sql 增加 mycat 注解

            sql = "/*!mycat:schema=" + "siss_user_" + dbSchema + " */" + sql;

            log.debug("加入处理后:" + sql);

            ReflectHelper.setFieldValue(boundSql, "sql", sql);
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        // TODO Auto-generated method stub
        if (target instanceof StatementHandler) {
            return Plugin.wrap(target, this);
        } else {
            return target;
        }
    }

    @Override
    public void setProperties(Properties properties) {
        // TODO Auto-generated method stub

    }

}
